#pragma once
#include "base/noncopyable.h"
#include "base/function.hpp"
#include "base/config.h"

#include <vector>
#include <memory.h>
namespace net_tools{
class Eventloop;
namespace base{
class Timeevery;
} // namespace base
namespace net{
class Connect;
namespace detail{
struct min_heartbeat_struct
{
  min_heartbeat_struct()
    :IS_ALIVE(0),
     SIZE(0)
  {
  };
  uint64_t                 IS_ALIVE;
  uint8_t                  SIZE;
  net_tools::net::Connect* connect_vector[64];
};
class heartbeat_struct
{
 public:
  heartbeat_struct()
    :free_min_heartbeat_vector_(),
     all_min_heartbeat_vector_()
  {
    No_Free_min_heartbeat_();
  };
  void No_Free_min_heartbeat_(){
    min_heartbeat_struct* new_ = new min_heartbeat_struct();
    free_min_heartbeat_vector_.push_back(new_);
    all_min_heartbeat_vector_.push_back(new_);
  };
  void Add_free_min_heartbeat_(min_heartbeat_struct* min_heartbeat_){
    free_min_heartbeat_vector_.push_back(min_heartbeat_);
  };
  std::vector<min_heartbeat_struct*> free_min_heartbeat_vector_;
  std::vector<min_heartbeat_struct*> all_min_heartbeat_vector_;
};
} // namespace detail
class Heartbeat : net_tools::base::noncopyable{
 public:
  Heartbeat(net_tools::Eventloop* eventloop,connect_func heartbeat_lose_func);
  ~Heartbeat(){};
  void Start();
  void Stop();
  void Timeout();
  void Add_heartbeat(Connect* connect);
  //only call by connect Heartbeat_Close_connect_todo
  void Del_heartbeat(Connect* connect);
  void Lose_heartbeat(Connect* connect);
  uint64_t index_vector_[65];
 private:
  void Now_full_add(Connect* connect);
  net_tools::Eventloop*       eventloop_;
  connect_func                heartbeat_lose_func_;
  detail::heartbeat_struct*   heart_struct_[_C::HEARTBEAT_VECTOR_SIZE];
  //now time
  uint32_t                    time_index_;
  //last one
  uint32_t                    free_time_index_;
  net_tools::base::Timeevery* timeevery_;
};
#define INDEX_VECTOR \
  {\
    0x0000000000000001,\
    0x0000000000000002,\
    0x0000000000000004,\
    0x0000000000000008,\
    0x0000000000000010,\
    0x0000000000000020,\
    0x0000000000000040,\
    0x0000000000000080,\
    0x0000000000000100,\
    0x0000000000000200,\
    0x0000000000000400,\
    0x0000000000000800,\
    0x0000000000001000,\
    0x0000000000002000,\
    0x0000000000004000,\
    0x0000000000008000,\
    0x0000000000010000,\
    0x0000000000020000,\
    0x0000000000040000,\
    0x0000000000080000,\
    0x0000000000100000,\
    0x0000000000200000,\
    0x0000000000400000,\
    0x0000000000800000,\
    0x0000000001000000,\
    0x0000000002000000,\
    0x0000000004000000,\
    0x0000000008000000,\
    0x0000000010000000,\
    0x0000000020000000,\
    0x0000000040000000,\
    0x0000000080000000,\
    0x0000000100000000,\
    0x0000000200000000,\
    0x0000000400000000,\
    0x0000000800000000,\
    0x0000001000000000,\
    0x0000002000000000,\
    0x0000004000000000,\
    0x0000008000000000,\
    0x0000010000000000,\
    0x0000020000000000,\
    0x0000040000000000,\
    0x0000080000000000,\
    0x0000100000000000,\
    0x0000200000000000,\
    0x0000400000000000,\
    0x0000800000000000,\
    0x0001000000000000,\
    0x0002000000000000,\
    0x0004000000000000,\
    0x0008000000000000,\
    0x0010000000000000,\
    0x0020000000000000,\
    0x0040000000000000,\
    0x0080000000000000,\
    0x0100000000000000,\
    0x0200000000000000,\
    0x0400000000000000,\
    0x0800000000000000,\
    0x1000000000000000,\
    0x2000000000000000,\
    0x4000000000000000,\
    0x8000000000000000,\
    0x0000000000000000,\
  }
} // namespace net
} // namespace net_tools